﻿using Alipay.AopSdk.Core;
using LPP.Core.Dtos;
using LPP.Service.MapServices;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Text.Json;

public class AmapLocationService : ILocationService
{
    private readonly HttpClient _httpClient;
    private readonly AmapConfig _config;
    private readonly ILogger<AmapLocationService> _logger;

    private const string DefaultExtensions = "base";
    private const string DefaultOutput = "json";

    public AmapLocationService(
        HttpClient httpClient,
        IOptions<AmapConfig> config,
        ILogger<AmapLocationService> logger)
    {
        _httpClient = httpClient;
        _httpClient.Timeout = TimeSpan.FromSeconds(10);
        _config = config.Value;
        _logger = logger;
    }

    private string BuildRequestUrl(double longitude, double latitude)
    {
        var queryString = $"key={_config.ApiKey}&location={longitude},{latitude}&extensions={DefaultExtensions}&output={DefaultOutput}";
        return $"{_config.WebApiUrl}/geocode/regeo?{queryString}";
    }

    private AmapResponse? ParseResponse(string content)
    {
        try
        {
            return JsonSerializer.Deserialize<AmapResponse>(content, new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            });
        }
        catch (JsonException ex)
        {
            _logger.LogError(ex, "解析高德地图API响应失败: {Content}", content);
            return null;
        }
    }

    public async Task<LocationResult> GetLocationInfoAsync(double longitude, double latitude)
    {
        try
        {
            var requestUrl = BuildRequestUrl(longitude, latitude);
            _logger.LogInformation("调用高德地图API，Url: {RequestUrl}", requestUrl);

            var response = await _httpClient.GetAsync(requestUrl);
            response.EnsureSuccessStatusCode();

            var content = await response.Content.ReadAsStringAsync();
            var result = ParseResponse(content);
            if (result == null || result.Status != "1")
            {
                _logger.LogWarning("高德地图API异常，返回: {Response}, 状态: {Status}", content, result?.Status);
                return new LocationResult
                {
                    Success = false,
                    Message = "获取位置信息失败"
                };
            }

            var locationInfo = new LocationInfo
            {
                Province = result.Regeocode.AddressComponent.Province,
                City = result.Regeocode.AddressComponent.City ?? "未知",
                District = result.Regeocode.AddressComponent.District ?? "未知",
                Address = result.Regeocode.FormattedAddress ?? "地址未解析",
                Street = result.Regeocode.AddressComponent.Street,
                StreetNumber = result.Regeocode.AddressComponent.StreetNumber
            };

            return new LocationResult
            {
                Success = true,
                Data = locationInfo
            };
        }
        catch (HttpRequestException ex) when (ex.StatusCode == System.Net.HttpStatusCode.Unauthorized)
        {
            _logger.LogError(ex, "高德地图API认证失败，检查ApiKey");
            return new LocationResult
            {
                Success = false,
                Message = "API认证失败，请检查配置"
            };
        }
        catch (TaskCanceledException ex)
        {
            _logger.LogError(ex, "调用高德地图API超时");
            return new LocationResult
            {
                Success = false,
                Message = "请求超时，请稍后重试"
            };
        }
        catch (JsonException ex)
        {
            _logger.LogError(ex, "解析高德地图API响应失败");
            return new LocationResult
            {
                Success = false,
                Message = "解析响应数据失败"
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取位置信息时发生未知错误");
            return new LocationResult
            {
                Success = false,
                Message = "服务器内部错误"
            };
        }
    }
    // API响应模型
    internal class AmapResponse
    {
        public string Status { get; set; }
        public string Info { get; set; }
        public string InfoCode { get; set; }
        public Regeocode Regeocode { get; set; }
    }
    internal class Regeocode
    {
        public AddressComponent AddressComponent { get; set; }
        public string FormattedAddress { get; set; }
    }
    internal class AddressComponent
    {
        public string Province { get; set; }
        public string City { get; set; }
        public string District { get; set; }
        public string Street { get; set; }
        public string StreetNumber { get; set; }
    }
}